<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MongoZzl {
    protected $mongodb;
    protected $dbname;
    protected $collection;
    protected $bulk;
    protected $writeConcern;
    public function __construct($config)
    {
        if (!$config['dbname'] || !$config['collection']) {
            # code...
            exit('参数错误');
        }
        $this->mongodb = new MongoDB\Driver\Manager("mongodb://localhost:27017");
        $this->dbname = $config['dbname'];
        $this->collection = $config['collection'];
        $this->bulk = new MongoDB\Driver\BulkWrite();
        $this->writeConcern   = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 100);
    }

    /**
     * @param array $where
     * @param array $option
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function query($where=[],$option=[])
    {
        $query = new MongoDB\Driver\Query($where,$option);
        $result = $this->mongodb->executeQuery("$this->dbname.$this->collection", $query)->toArray();

        return $result;
    }

    /**
     * @param array $where
     * @return int
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getCount($where=[])
    {
        $command = new MongoDB\Driver\Command(['count' => $this->collection,'query'=>(object)$where]);
        $result = $this->mongodb->executeCommand($this->dbname,$command);

        $res = $result->toArray();
        $cnt = 0;
        if ($res) {
            # code...
            $cnt = $res[0]->n;
        }

        return $cnt;
    }

    /**
     * @param array $where
     * @param int $page
     * @param int $limit
     * @return false|string
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function page($where=[],$page=1,$limit=10)
    {

        $count = $this->getCount($where);
        $data['count'] = $count;
        $endpage = ceil($count/$limit);
        if ($page>$endpage) {
            # code...
            $page = $endpage;
        }elseif ($page <1) {
            $page = 1;
        }

        $skip = ($page>0?($page-1)*$limit:0);
        $options = [
            'skip'     => $skip,
            'limit'    => $limit
        ];
        $data['data'] = $this->query($where,$options);
        $data['page'] = $endpage;
        return $data;
    }

    /**
     * @param array $where
     * @param array $update
     * @param bool $upsert
     * @return int|null
     */
    public function update($data,$upsert=false)
    {
        foreach ($data as $v){
            $this->bulk->update($v['where'],['$set' => $v['update']], ['multi' => true, 'upsert' => $upsert]);
        }
        $result = $this->mongodb->executeBulkWrite("$this->dbname.$this->collection", $this->bulk, $this->writeConcern);
        return $result->getModifiedCount();
    }

    public function update_many($filter,$data,$upsert=false){
        $BulkWrite=new MongoDB\Driver\BulkWrite();
        $BulkWrite->update($filter,$data,['multi' => true, 'upsert' => $upsert]);

        $result = $this->mongodb->executeBulkWrite("$this->dbname.$this->collection", $this->bulk, $this->writeConcern);
        return $result->getModifiedCount();
    }

    /**
     * @param array $data
     * @return mixed
     */
    public function insert($data=[])
    {
        $result = $this->bulk->insert($data);
        return $result->getInsertedCount();
    }

    /**
     * @param array $where
     * @param int $limit
     * @return mixed
     */
    public function delete($where=[],$limit=1)
    {
        $result = $this->bulk->delete($where,['limit'=>$limit]);
        return $result->getDeletedCount();
    }

}
